package com.cencat.order.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.*;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalTime;
import java.util.List;

/**
 * 路线信息数据传输对象
 * 
 * @author cencat
 * @date 2024-01-20
 */
@Data
@Accessors(chain = true)
public class RouteDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 路线ID(更新时必填)
     */
    private Long routeId;

    /**
     * 路线编号
     */
    @Size(max = 50, message = "路线编号长度不能超过50个字符")
    private String routeCode;

    /**
     * 路线名称
     */
    @NotBlank(message = "路线名称不能为空")
    @Size(max = 100, message = "路线名称长度不能超过100个字符")
    private String routeName;

    /**
     * 路线描述
     */
    @Size(max = 500, message = "路线描述长度不能超过500个字符")
    private String routeDescription;

    /**
     * 起点名称
     */
    @NotBlank(message = "起点名称不能为空")
    @Size(max = 100, message = "起点名称长度不能超过100个字符")
    private String startPointName;

    /**
     * 起点地址
     */
    @NotBlank(message = "起点地址不能为空")
    @Size(max = 200, message = "起点地址长度不能超过200个字符")
    private String startPointAddress;

    /**
     * 起点经度
     */
    @NotNull(message = "起点经度不能为空")
    @DecimalMin(value = "-180.0", message = "起点经度值不正确")
    @DecimalMax(value = "180.0", message = "起点经度值不正确")
    private BigDecimal startLongitude;

    /**
     * 起点纬度
     */
    @NotNull(message = "起点纬度不能为空")
    @DecimalMin(value = "-90.0", message = "起点纬度值不正确")
    @DecimalMax(value = "90.0", message = "起点纬度值不正确")
    private BigDecimal startLatitude;

    /**
     * 终点名称
     */
    @NotBlank(message = "终点名称不能为空")
    @Size(max = 100, message = "终点名称长度不能超过100个字符")
    private String endPointName;

    /**
     * 终点地址
     */
    @NotBlank(message = "终点地址不能为空")
    @Size(max = 200, message = "终点地址长度不能超过200个字符")
    private String endPointAddress;

    /**
     * 终点经度
     */
    @NotNull(message = "终点经度不能为空")
    @DecimalMin(value = "-180.0", message = "终点经度值不正确")
    @DecimalMax(value = "180.0", message = "终点经度值不正确")
    private BigDecimal endLongitude;

    /**
     * 终点纬度
     */
    @NotNull(message = "终点纬度不能为空")
    @DecimalMin(value = "-90.0", message = "终点纬度值不正确")
    @DecimalMax(value = "90.0", message = "终点纬度值不正确")
    private BigDecimal endLatitude;

    /**
     * 路线距离(公里)
     */
    @DecimalMin(value = "0.1", message = "路线距离不能小于0.1公里")
    @DecimalMax(value = "10000.0", message = "路线距离不能大于10000公里")
    private BigDecimal routeDistance;

    /**
     * 预计时长(分钟)
     */
    @Min(value = 1, message = "预计时长不能小于1分钟")
    @Max(value = 10080, message = "预计时长不能大于7天")
    private Integer estimatedDuration;

    /**
     * 路线状态(0-禁用 1-启用 2-维护中)
     */
    @Min(value = 0, message = "路线状态值不正确")
    @Max(value = 2, message = "路线状态值不正确")
    private Integer routeStatus;

    /**
     * 路线类型(1-固定路线 2-临时路线 3-优化路线)
     */
    @NotNull(message = "路线类型不能为空")
    @Min(value = 1, message = "路线类型值不正确")
    @Max(value = 3, message = "路线类型值不正确")
    private Integer routeType;

    /**
     * 优先级(1-低 2-中 3-高 4-紧急)
     */
    @Min(value = 1, message = "优先级值不正确")
    @Max(value = 4, message = "优先级值不正确")
    private Integer priority;

    /**
     * 最大载重(吨)
     */
    @DecimalMin(value = "0.1", message = "最大载重不能小于0.1吨")
    @DecimalMax(value = "100.0", message = "最大载重不能大于100吨")
    private BigDecimal maxLoadWeight;

    /**
     * 最大体积(立方米)
     */
    @DecimalMin(value = "0.1", message = "最大体积不能小于0.1立方米")
    @DecimalMax(value = "1000.0", message = "最大体积不能大于1000立方米")
    private BigDecimal maxLoadVolume;

    /**
     * 车辆类型要求
     */
    @Size(max = 100, message = "车辆类型要求长度不能超过100个字符")
    private String vehicleTypeRequirement;

    /**
     * 司机技能要求
     */
    @Size(max = 200, message = "司机技能要求长度不能超过200个字符")
    private String driverSkillRequirement;

    /**
     * 服务时间窗开始
     */
    @JsonFormat(pattern = "HH:mm:ss")
    private LocalTime serviceTimeStart;

    /**
     * 服务时间窗结束
     */
    @JsonFormat(pattern = "HH:mm:ss")
    private LocalTime serviceTimeEnd;

    /**
     * 允许延迟时间(分钟)
     */
    @Min(value = 0, message = "允许延迟时间不能小于0分钟")
    @Max(value = 1440, message = "允许延迟时间不能大于1天")
    private Integer allowDelayMinutes;

    /**
     * 路线成本
     */
    @DecimalMin(value = "0.0", message = "路线成本不能小于0")
    private BigDecimal routeCost;

    /**
     * 燃油成本
     */
    @DecimalMin(value = "0.0", message = "燃油成本不能小于0")
    private BigDecimal fuelCost;

    /**
     * 过路费
     */
    @DecimalMin(value = "0.0", message = "过路费不能小于0")
    private BigDecimal tollFee;

    /**
     * 其他费用
     */
    @DecimalMin(value = "0.0", message = "其他费用不能小于0")
    private BigDecimal otherFee;

    /**
     * 路线点位信息
     */
    private List<RoutePointDTO> routePoints;

    /**
     * 是否启用时间窗
     */
    private Boolean enableTimeWindow;

    /**
     * 是否启用容量限制
     */
    private Boolean enableCapacityLimit;

    /**
     * 是否启用优先级
     */
    private Boolean enablePriority;

    /**
     * 路线标签(多个用逗号分隔)
     */
    @Size(max = 200, message = "路线标签长度不能超过200个字符")
    private String routeTags;

    /**
     * 适用天气条件
     */
    @Size(max = 100, message = "适用天气条件长度不能超过100个字符")
    private String weatherConditions;

    /**
     * 路况要求
     */
    @Size(max = 100, message = "路况要求长度不能超过100个字符")
    private String roadConditions;

    /**
     * 特殊要求
     */
    @Size(max = 500, message = "特殊要求长度不能超过500个字符")
    private String specialRequirements;

    /**
     * 备注
     */
    @Size(max = 500, message = "备注长度不能超过500个字符")
    private String remark;

    /**
     * 扩展字段1
     */
    @Size(max = 200, message = "扩展字段1长度不能超过200个字符")
    private String extField1;

    /**
     * 扩展字段2
     */
    @Size(max = 200, message = "扩展字段2长度不能超过200个字符")
    private String extField2;

    /**
     * 扩展字段3
     */
    @Size(max = 200, message = "扩展字段3长度不能超过200个字符")
    private String extField3;

    /**
     * 路线点位数据传输对象
     */
    @Data
    @Accessors(chain = true)
    public static class RoutePointDTO implements Serializable {

        private static final long serialVersionUID = 1L;

        /**
         * 点位ID(更新时必填)
         */
        private Long pointId;

        /**
         * 点位名称
         */
        @NotBlank(message = "点位名称不能为空")
        @Size(max = 100, message = "点位名称长度不能超过100个字符")
        private String pointName;

        /**
         * 点位地址
         */
        @NotBlank(message = "点位地址不能为空")
        @Size(max = 200, message = "点位地址长度不能超过200个字符")
        private String pointAddress;

        /**
         * 经度
         */
        @NotNull(message = "经度不能为空")
        @DecimalMin(value = "-180.0", message = "经度值不正确")
        @DecimalMax(value = "180.0", message = "经度值不正确")
        private BigDecimal longitude;

        /**
         * 纬度
         */
        @NotNull(message = "纬度不能为空")
        @DecimalMin(value = "-90.0", message = "纬度值不正确")
        @DecimalMax(value = "90.0", message = "纬度值不正确")
        private BigDecimal latitude;

        /**
         * 点位顺序
         */
        @NotNull(message = "点位顺序不能为空")
        @Min(value = 1, message = "点位顺序不能小于1")
        private Integer pointOrder;

        /**
         * 点位类型(1-起点 2-途经点 3-终点)
         */
        @NotNull(message = "点位类型不能为空")
        @Min(value = 1, message = "点位类型值不正确")
        @Max(value = 3, message = "点位类型值不正确")
        private Integer pointType;

        /**
         * 预计到达时间
         */
        @JsonFormat(pattern = "HH:mm:ss")
        private LocalTime estimatedArrivalTime;

        /**
         * 停留时间(分钟)
         */
        @Min(value = 0, message = "停留时间不能小于0分钟")
        @Max(value = 1440, message = "停留时间不能大于1天")
        private Integer stayDuration;

        /**
         * 服务时间窗开始
         */
        @JsonFormat(pattern = "HH:mm:ss")
        private LocalTime serviceTimeStart;

        /**
         * 服务时间窗结束
         */
        @JsonFormat(pattern = "HH:mm:ss")
        private LocalTime serviceTimeEnd;

        /**
         * 联系人
         */
        @Size(max = 50, message = "联系人长度不能超过50个字符")
        private String contactPerson;

        /**
         * 联系电话
         */
        @Pattern(regexp = "^1[3-9]\\d{9}$", message = "联系电话格式不正确")
        private String contactPhone;

        /**
         * 备注
         */
        @Size(max = 200, message = "备注长度不能超过200个字符")
        private String remark;
    }
}